package no.uib.hplims.models;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import no.uib.hplims.models.peptideinformation.PeptideInformation;

import org.vaadin.appfoundation.persistence.facade.FacadeFactory;

import com.vaadin.ui.CustomComponent;

public class PeptideFactory extends CustomComponent {

	private static final long serialVersionUID = -963355718776671544L;

	public PeptideFactory() {

	}

	public Peptide createPeptide(String query, ArrayList<BlastInfo> results,
			MyOrder order, String species) {

		System.out.println("Starting creation of peptide");
		System.out.println(results);

		String peptideSequence = query;

		String peptideName = "";

		if (results.size() > 0) {
			if (results.size() == 1) {
				peptideName = generatePeptideName(results.get(0));
			} else {
				peptideName = "Peptide needs revision. Double click to edit.";
			}
		} else {
			peptideName = "No blast hit.";
		}

		System.out.println("Creating PID");
		// Prepare peptide information object for future access.
		PeptideInformation pi = new PeptideInformation();
		FacadeFactory.getFacade().store(pi);
		Long peptideInformationID = pi.getId();
		System.out.println("PID created.");

		Peptide peptide = new Peptide();
		if (results.size() == 1) {
			peptide.setUniProtAccession(results.get(0)
					.getUniProtAccessionNumber());
		} else {
			peptide.setUniProtAccession(null);
		}
		peptide.setPeptideName(peptideName);
		peptide.setPeptideSequence(peptideSequence);
		peptide.setCreatedOn(new Date());
		peptide.setBelongsToOrder(order);
		peptide.setBlastHits(results);
		peptide.setSpecies(species);
		peptide.setPeptideInformationID(peptideInformationID);

		if (results.size() == 1) {
			peptide.setSelectedProtein(results.get(0));
		}

		// Save the peptide
		FacadeFactory.getFacade().store(peptide);

		return peptide;
	}

	public static String generatePeptideName(BlastInfo bi) {
		String name = bi.getProteinName() + "_"
				+ bi.getUniProtAccessionNumber() + "_"
				+ bi.getProteinShortName() + "_" + bi.getPeptideStart() + "_"
				+ bi.getPeptideEnd();
		return name;
	}

	public ArrayList<Peptide> updatePeptide(String query,
			ArrayList<BlastInfo> results, MyOrder order) {

		String buildQuery = "SELECT p FROM Peptide AS p WHERE p.peptideSequence LIKE :sequence"
				+ " AND p.belongsToOrder = :order";
		Map<String, Object> parameters = new HashMap<String, Object>();
		parameters.put("sequence", query);
		parameters.put("order", order);

		List<Peptide> list = FacadeFactory.getFacade().list(buildQuery,
				parameters);

		String peptideName = "";

		for (Peptide peptide : list) {
			if (peptide.getSelectedProtein() == null) {

				if (results.size() > 0) {
					if (results.size() == 1) {
						peptideName = generatePeptideName(results.get(0));
						peptide.setSelectedProtein(results.get(0));
						peptide.setUniProtAccession(results.get(0)
								.getUniProtAccessionNumber());
					} else {
						peptideName = "Peptide needs revision. Double click to edit.";
						peptide.setUniProtAccession(null);
					}
				} else {
					peptideName = "No blast hit.";
					peptide.setUniProtAccession(null);
				}

				peptide.setPeptideName(peptideName);
				peptide.setPeptideSequence(query);
				peptide.setBlastHits(results);
			}

		}

		FacadeFactory.getFacade().storeAll(list);

		ArrayList<Peptide> p = new ArrayList<Peptide>();
		p.addAll(list);
		return p;
	}
}
